package org.dicr.sys.linux;

import java.io.*;

/**
 * Загрузка процессора.
 * <P>
 * Данные о загрузки процессора
 * </P>
 * <P>
 * <DL>
 * <DT><CODE>timeStamp</CODE></DT>
 * <DD>момент времени снятия показаний;</DD>
 * <DT><CODE>numProcesses</CODE></DT>
 * <DD>число запущенных в системе процессов;</DD>
 * <DT><CODE>loadAvg</CODE></DT>
 * <DD>среднее число процессов в очереди на исполнение за последние 1, 5 и 15 минут; </DD>
 * <DT><CODE>timesUser, timeSystem, timesIdle</CODE></DT>
 * <DD>число единиц времени, в течении которого система выполняла пользовательские, системные процессы и простаивала с
 * момента загрузки системы. </DD>
 * </DL>
 * </P>
 * <P>
 * Расчет загрузки процессора.
 * </P>
 * <P>
 * Можно рассчитать среднюю загрузку процессора в процентах за время, большее чем время кэширования данных. Для этого
 * делается пара замеров {@link CPUInfo#getLoad} с периодом большим чем время кеширования {@link CPUInfo#getCacheTime} и
 * затем вычисляется разница:
 * 
 * <PRE>
 *  // measure data CPULoadData data1 = CPUInfo.getLoadData(); Thread.sleep(CPUInfo.getCachePeriod() * 2);
 * CPULoadData data2 = CPUInfo.getLoadData(); // calculate deltas long deltaUser = data2.timesUser - data1.timesUser;
 * long deltaSystem = data2.timesSystem - data1.timesSystem; long deltaIdle = data2.timesIdle - data1.timesIdle; long
 * detaTotal = deltaUser + deltaSystem + deltaIdle // calculate avarage percents int userPercents = Math.round(deltaUser /
 * deltaTotal * 100); int systemPercents = Math.round(deltaSystem / deltaTotal * 100); int idlePercents =
 * Math.round(deltaIdle / deltaTotal * 100);
 * 
 * </PRE>
 * 
 * </P>
 * 
 * @author Igor A Tarasov <java@dicr.org>
 * @version 1.0
 * @see CPUInfo
 * @see java.lang.System#currentTimeMillis
 */
public class CPULoadData implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final int numProcesses;

	private final float[] loadAvg;

	private final long timesSystem;

	private final long timesUser;

	private final long timesIdle;

	private final long timeStamp = System.currentTimeMillis();

	/**
	 * Constructor
	 * 
	 * @param theNumProcesses
	 * @param theLoadAvg
	 * @param theTimesSystem
	 * @param theTimesUser
	 * @param theTimesIdle
	 */
	protected CPULoadData(final int theNumProcesses, final float[] theLoadAvg, final long theTimesSystem, final long theTimesUser, final long theTimesIdle) {
		super();
		if (theNumProcesses < 0) throw new IllegalArgumentException("numProcesses: " + theNumProcesses);
		this.numProcesses = theNumProcesses;
		if (theLoadAvg == null || theLoadAvg.length != 3) throw new IllegalArgumentException("incorrect loadAvg");
		for (int i = 0; i < 3; i++) {
			if (theLoadAvg[i] < 0) throw new IllegalArgumentException("loadAvg[" + i + "]: " + theLoadAvg[i]);
		}
		this.loadAvg = theLoadAvg;
		if (theTimesSystem < 0) throw new IllegalArgumentException("timesSystem: " + theTimesSystem);
		this.timesSystem = theTimesSystem;
		if (theTimesUser < 0) throw new IllegalArgumentException("timesUser: " + theTimesUser);
		this.timesUser = theTimesUser;
		if (theTimesIdle < 0) throw new IllegalArgumentException("timesIdle: " + theTimesIdle);
		this.timesIdle = theTimesIdle;
	}

	/**
	 * Возвращает время данных.
	 * 
	 * @return время данных в формате <CODE>System.currentTimeMillis()</CODE>.
	 */
	public long getTimeStamp() {
		return this.timeStamp;
	}

	/**
	 * Возвращает загрузку процессов.
	 * 
	 * @return float[3] loadAvg.
	 */
	public float[] getLoadAvg() {
		return this.loadAvg;
	}

	/**
	 * Возвращает число процессов.
	 * 
	 * @return число запущенных процессов.
	 */
	public int getNumProcesses() {
		return this.numProcesses;
	}

	/**
	 * Возвращает время простоя.
	 * 
	 * @return время простоя.
	 */
	public long getTimesIdle() {
		return this.timesIdle;
	}

	/**
	 * Возвращает пользовательское время.
	 * 
	 * @return пользовательское время.
	 */
	public long getTimesSystem() {
		return this.timesSystem;
	}

	/**
	 * Возвращает системное время.
	 * 
	 * @return системное время.
	 */
	public long getTimesUser() {
		return this.timesUser;
	}

	/**
	 * Преобразование в строку.
	 * 
	 * @return строковое представление.
	 */
	@Override public String toString() {
		return "CPUInfoData[" + this.timeStamp + "]";
	}
}
